package cc.shacocloud.redis.study.lock.impl;

import cc.shacocloud.redis.study.lock.MutexLock;
import cc.shacocloud.redis.study.lock.MutexLockMo;
import cc.shacocloud.redis.study.util.redis.RLock;
import cc.shacocloud.redis.study.util.redis.RedisLockUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Date;

/**
 * redis实现互斥锁
 */
public class RedisMutexLock implements MutexLock {

    @NotNull
    @Override
    public MutexLockMo tryLock(@NotNull String lockName, String reentrantCertificate, @NotNull Date leaseTime) {
        DateTime date = DateUtil.date();
        if (leaseTime.before(date)) throw new IllegalArgumentException("过期时间不可以在当前时间前！");

        reentrantCertificate = reentrantCertificate == null ? IdUtil.objectId() : reentrantCertificate;

        RLock rLock = RedisLockUtil.tryLock(lockName, reentrantCertificate, DateUtil.between(date, leaseTime, DateUnit.MS));

        return new MutexLockMo(rLock.getLockName(), rLock.getReentrantCertificate(),
                rLock.getExpireDate(), rLock.isStatus());
    }

    @Nullable
    @Override
    public MutexLockMo tryUnlock(@NotNull String lockName, @NotNull String reentrantCertificate) {
        RLock rLock = RedisLockUtil.tryUnlock(lockName, reentrantCertificate);
        return new MutexLockMo(rLock.getLockName(), rLock.getReentrantCertificate(),
                rLock.getExpireDate(), rLock.isStatus());
    }

}
